package com.fwzhang.third.collectionframework.collection.queue;

import java.util.Queue;

/**
 * 双端队列
 * 继承Queue接口，增加了对双端数据的处理
 *
 * @param <E>
 */
public interface DequeInterface<E> extends Queue<E> {

    /**
     * 在双端队列头部添加数据
     *
     * @param e 需要添加的数据
     * @throws IllegalStateException 当前队列容量已满时，添加数据，抛出该异常
     * @throws ClassCastException 如果指定元素的类阻止将其添加到此队列
     * @throws NullPointerException 如果指定元素为null并且当前队列对象不允许存储null
     * @throws IllegalArgumentException 如果指定元素的某些属性阻止将其添加到此数据块中
     */
    void addFirst(E e);

    /**
     * 在双端队列的尾部添加数据
     * 相当于 {@link #add} 方法
     *
     * @param e 需要添加的数据
     * @throws IllegalStateException 当前队列容量已满时，添加数据，抛出该异常
     * @throws ClassCastException 如果指定元素的类阻止将其添加到此队列
     * @throws NullPointerException 如果指定元素为null并且当前队列对象不允许存储null
     * @throws IllegalArgumentException 如果指定元素的某些属性阻止将其添加到此数据块中
     */
    void addLast(E e);

    boolean add(E e);

    /**
     * 在双端队列头部添加数据
     *
     * @param e 需要添加的数据
     * @return true - 添加成功；false - 添加失败
     * @throws ClassCastException       如果指定元素的类阻止将其添加到此队列
     * @throws NullPointerException     如果指定元素为null并且当前队列对象不允许存储null
     * @throws IllegalArgumentException 如果指定元素的某些属性阻止将其添加到此数据块中
     */
    boolean offerFirst(E e);

    /**
     * 在双端队列尾部添加数据
     * 相当于 {@link #offer(Object)} 方法
     *
     * @param e 需要添加的数据
     * @return true - 添加成功；false - 添加失败
     * @throws ClassCastException       如果指定元素的类阻止将其添加到此队列
     * @throws NullPointerException     如果指定元素为null并且当前队列对象不允许存储null
     * @throws IllegalArgumentException 如果指定元素的某些属性阻止将其添加到此数据块中
     */
    boolean offerLast(E e);

    boolean offer(E e);

    /**
     * 返回并删除队列的头部数据
     *
     * @return 队列的头部数据
     * @throws java.util.NoSuchElementException 队列为空时抛出该异常
     */
    E removeFirst();

    /**
     * 返回并删除队列的尾部元素
     * 与{@link #remove()} 作用相同
     *
     * @return 队列的尾部数据
     * @throws java.util.NoSuchElementException 队列为空时抛出该异常
     */
    E removeLast();

    E remove();

    /**
     * 返回并删除队列的头部数据
     *
     * @return 队列的头部数据 or null(队列为空时)
     */
    E pollFirst();

    /**
     * 返回并删除队列的尾部数据
     * 与 {@link #poll()} 方法相同
     *
     * @return 队列的尾部数据 or null(队列为空时)
     */
    E pollLast();

    E poll();

    /**
     * 返回队列的头部数据
     *
     * @return 队列的头部数据
     * @throws java.util.NoSuchElementException 队列为空
     */
    E getFirst();

    /**
     * 返回队列的尾部数据
     * 与{@link #element()}相同
     *
     * @return 队列的尾部数据
     * @throws java.util.NoSuchElementException 队列为空
     */
    E getLast();

    E element();

    /**
     * 返回队列的头部数据
     *
     * @return 队列头部数据 or null
     */
    E peekFirst();

    /**
     * 返回队列的尾部数据
     * 与{@link #peek()}相同
     *
     * @return 队列尾部数据 or null
     */
    E peekLast();

    E peek();

    /**
     * 按照从前到后的顺序查找，删除第一个出现的指定数据
     * @param o 指定数据
     * @return 删除是否成功
     */
    boolean removeFirstOccurrence(Object o);

    /**
     * 按照从后向前的顺序查找，删除第一个出现的指定数据
     * @param o 指定数据
     * @return 删除结果
     */
    boolean removeLastOccurrence(Object o);

    // 栈操作

    /**
     * 栈操作，添加元素，入栈
     * 与{@link #addFirst} 相同
     *
     * @param e 栈元素
     */
    void push(E e);

    /**
     * 出栈
     * 与{@link #removeFirst()}相同
     *
     * @return 栈元素
     */
    E pop();



}
